/**
 * File: NodeNextSeedByLength.java
 * Created by: mhaimel
 * Created on: Apr 30, 2010
 * CVS:  $Id: NodeNextSeedByLength.java 1.0 Apr 30, 2010 10:00:39 AM mhaimel Exp $
 */
package uk.ac.ebi.curtain.model.graph.curtain.filter;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

import uk.ac.ebi.curtain.model.graph.Node;
import uk.ac.ebi.curtain.model.graph.GraphAccess.TouchEach;
import uk.ac.ebi.curtain.model.graph.curtain.ContigInfo;
import uk.ac.ebi.curtain.model.graph.curtain.ReadWrapper;
import uk.ac.ebi.curtain.utils.BitUtil;

/**
 * @author mhaimel
 *
 */
public class NodeNextSeedByLength implements TouchEach<Node<ContigInfo, ReadWrapper>> {
	private final AtomicLong minLength = new AtomicLong(0);
	private final AtomicReference<Node<ContigInfo, ReadWrapper>> seed = new AtomicReference<Node<ContigInfo,ReadWrapper>>();
	private final int usedFlag;
	
	public NodeNextSeedByLength(long minLength, int usedFlag) {
		this.minLength.set(minLength);
		this.usedFlag = usedFlag;
	}

	@Override
	public void touch(Node<ContigInfo, ReadWrapper> node) {
		if(null != node 
				&& node.isActive()
				&& !BitUtil.hasFlag(node.getStatus().get(),this.usedFlag)
				&& node.getValue().getLength() >= minLength.get()
				){
			do{
				Node<ContigInfo, ReadWrapper> curr = seed.get();
				if(null == curr){
					if(seed.compareAndSet(curr, node)){
						break;
					}
				} else if(node.getValue().getLength() > curr.getValue().getLength()){
					if(seed.compareAndSet(curr, node)){
						break;
					}
				} else {
					break;
				}
			}while(true);
		}
	}
	
	public Node<ContigInfo, ReadWrapper> getSeed() {
		return seed.get();
	}
	
	public void reset() {
		this.seed.set(null);
	}
}
